#ifndef _CAPP_H_
#define _CAPP_H_

#include <SDL.h>
#include "csurface.h"
#include "controller.h"
#include "glview.h"

class GLController : public Controller
{
public:
GLController(GLView * _glView)
	: Running(true), Surf_Display(NULL), Surf_Test(NULL), glView(_glView){}

	int OnExecute()
	{
		if(OnInit() == false) {
			return -1;
		}
		SDL_Event Event;
		while(Running) {
			while(SDL_PollEvent(&Event)) {
				OnEvent(&Event);
			}

			OnLoop();
			OnRender();
		}
		OnCleanup();
		return 0;
	}

public:
	bool OnInit(int _width = 1024, int _height = 768)
	{
		/* Information about the current video settings. */
		const SDL_VideoInfo* info = NULL;

		bpp = 0;
		flags = 0;
		if( SDL_Init( SDL_INIT_VIDEO ) < 0 ) 
		{			
			throw(SDL_GetError());
			return false;
		}
		info = SDL_GetVideoInfo( );
		if( !info ) 
		{
			throw("Video query failed: %s\n");				
			return false;
		}

		bpp = info->vfmt->BitsPerPixel;

		SDL_GL_SetAttribute( SDL_GL_RED_SIZE, 5 );
		SDL_GL_SetAttribute( SDL_GL_GREEN_SIZE, 5 );
		SDL_GL_SetAttribute( SDL_GL_BLUE_SIZE, 5 );
		SDL_GL_SetAttribute( SDL_GL_DEPTH_SIZE, 16 );
		SDL_GL_SetAttribute( SDL_GL_DOUBLEBUFFER, 1 );

		flags = SDL_OPENGL | SDL_RESIZABLE; //SDL_FULLSCREEN;

		if( SDL_SetVideoMode( _width, _height, bpp, flags ) == 0 ) {
			/* 
			 * This could happen for a variety of reasons,
			 * including DISPLAY not being set, the specified
			 * resolution not being available, etc.
			 */
			throw("Video mode set failed: ");
			return false;
		}

		glView->init(_width, _height);
		return true;
	}

	void OnEvent(SDL_Event* Event)
	{
		Controller::OnEvent(Event);
	}

	void OnLoop()
	{
	}

	void OnRender()
	{

		glView->onDraw();
		SDL_GL_SwapBuffers( );
	}

	void OnCleanup()
	{
		SDL_FreeSurface(Surf_Display);
		SDL_FreeSurface(Surf_Test);
		SDL_Quit();
	}

	void OnExit ()
	{
		Running = false ;
	}

	void OnLButtonDown (int mX, int mY)
	{
		//Running = false ;
		glView->setMousePos (mX, mY);
		glView->setLButtonDown( true );
	}

	void OnLButtonUp (int mX, int mY)
	{
		//Running = false;
		glView->setMousePos (mX, mY);
		glView->setLButtonDown( false);
	}

	void OnRButtonDown (int mX, int mY)
	{
		//Running = false ;
		glView->setMousePos (mX, mY);
		glView->setRButtonDown( true);
	}

	void OnRButtonUp (int mX, int mY)
	{
		//Running = false;
		glView->setRButtonDown( false);
	}

	void OnMButtonDown(int mX, int mY)
	{
		glView->setMousePos (mX, mY);
		glView->setMButtonDown( true);
	}

	void OnMButtonUp(int mX, int mY)
	{
		glView->setMousePos (mX, mY);
	}
	void OnMouseMove(int mX, int mY, int relX, int relY, bool Left,bool Right,bool Middle)
	{
		//Running = false;
		if (Middle)
		{
			glView->rotateCamera(mX, mY);
		}
		else if (Right)
		{
			glView->zoomCamera (mY);
		}
	}

	void OnResize(int w,int h)
	{
		//Running = false;
		SDL_SetVideoMode(w, h, bpp, flags);
		glView->resize(w,h);
	}

protected:
	bool             Running;
	SDL_Surface *    Surf_Display;
	SDL_Surface *    Surf_Test ;
	GLView      *    glView ;

	int bpp ;
	int flags ;
};



#endif
